import { Injectable, NotFoundException, BadRequestException, ForbiddenException } from '@nestjs/common'
import { DatabaseService } from '../../database/database.service'
import { LoggerService } from '../../common/logger/logger.service'
import {
  CreateContentDto,
  UpdateContentDto,
  QueryContentDto,
  PublishContentDto,
  ContentResponseDto,
  ContentStatsDto,
  ContentType,
  ContentFormat,
  ContentStatus,
  BulkContentOperationDto
} from '../../common/dto/content.dto'
import { UserRole, PostStatus } from '@prisma/client'
import { PaginatedResponseDto } from '../../common/dto/pagination.dto'

@Injectable()
export class ContentService {
  constructor(
    private readonly databaseService: DatabaseService,
    private readonly logger: LoggerService
  ) {}

  // 生成slug的辅助方法
  private generateSlug(title: string): string {
    return title
      .toLowerCase()
      .replace(/[^a-z0-9\u4e00-\u9fa5]+/g, '-')
      .replace(/^-+|-+$/g, '')
  }

  private transformToContentResponse(post: any): ContentResponseDto {
    return {
      id: post.id,
      title: post.title,
      subtitle: post.subtitle,
      content: post.content,
      excerpt: post.excerpt,
      type: ContentType.ARTICLE,
      status: post.status as ContentStatus,
      format: ContentFormat.MARKDOWN,
      slug: post.slug,
      category: post.category
        ? {
            id: post.category.id,
            name: post.category.name,
            slug: post.category.slug
          }
        : undefined,
      author: post.author
        ? {
            id: post.author.id,
            username: post.author.username,
            nickname: post.author.username,
            avatar: undefined
          }
        : undefined,
      tags: post.tags?.map((tagRelation: any) => tagRelation.tag.name) || [],
      featuredImage: post.featuredImage,
      featuredImageAlt: post.featuredImageAlt,
      publishedAt: post.publishedAt,
      views: post.views || 0,
      likesCount: post.likesCount || 0,
      commentsCount: post.commentsCount || 0,
      bookmarksCount: post.bookmarksCount || 0,
      sortOrder: post.sortOrder || 0,
      version: post.version || 1,
      createdAt: post.createdAt,
      updatedAt: post.updatedAt
    }
  }

  // 创建文章
  async createPost(
    data: {
      title: string
      content: string
      excerpt?: string
      categoryId?: string
      tags?: string[]
      status?: PostStatus
    },
    authorId: string
  ) {
    try {
      const postData: any = {
        title: data.title,
        slug: this.generateSlug(data.title),
        content: data.content,
        excerpt: data.excerpt,
        status: data.status || PostStatus.DRAFT,
        author: { connect: { id: authorId } }
      }

      if (data.categoryId) {
        postData.category = { connect: { id: data.categoryId } }
      }

      // 处理标签
      if (data.tags && data.tags.length > 0) {
        postData.tags = {
          create: data.tags.map(tagId => ({
            tag: { connect: { id: tagId } }
          }))
        }
      }

      const post = await this.databaseService.post.create({
        data: postData,
        include: {
          author: { select: { id: true, username: true, email: true } },
          category: true,
          tags: { include: { tag: true } }
        }
      })

      this.logger.log(`Post created: ${post.id}`, 'ContentService')
      return this.transformToContentResponse(post)
    } catch (error) {
      this.logger.error(`Failed to create post: ${error.message}`, error.stack, 'ContentService')
      throw new BadRequestException('创建文章失败')
    }
  }

  // 获取文章列表
  async getPosts(params: {
    page?: number
    limit?: number
    status?: PostStatus
    categoryId?: string
    authorId?: string
    search?: string
  }) {
    try {
      const { page = 1, limit = 10, status, categoryId, authorId, search } = params
      const skip = (page - 1) * limit

      const where: any = {}
      if (status) where.status = status
      if (categoryId) where.categoryId = categoryId
      if (authorId) where.authorId = authorId
      if (search) {
        where.OR = [
          { title: { contains: search, mode: 'insensitive' } },
          { content: { contains: search, mode: 'insensitive' } }
        ]
      }

      const [posts, total] = await Promise.all([
        this.databaseService.post.findMany({
          where,
          skip,
          take: limit,
          orderBy: { createdAt: 'desc' },
          include: {
            author: { select: { id: true, username: true, email: true } },
            category: true,
            tags: { include: { tag: true } },
            _count: { select: { comments: true } }
          }
        }),
        this.databaseService.post.count({ where })
      ])

      return {
        data: posts,
        pagination: {
          page,
          limit,
          total,
          pages: Math.ceil(total / limit)
        }
      }
    } catch (error) {
      this.logger.error(`Failed to get posts: ${error.message}`, error.stack, 'ContentService')
      throw new BadRequestException('获取文章列表失败')
    }
  }

  // 获取文章详情
  async getPostById(id: string, includeViews = false) {
    try {
      const post = await this.databaseService.post.findUnique({
        where: { id },
        include: {
          author: { select: { id: true, username: true, email: true } },
          category: true,
          tags: { include: { tag: true } },
          comments: {
            where: { status: 'APPROVED' },
            include: {
              user: { select: { id: true, username: true } }
            },
            orderBy: { createdAt: 'desc' }
          }
        }
      })

      if (!post) {
        throw new NotFoundException('文章不存在')
      }

      // 增加浏览量
      // 注释掉views字段更新，因为Post模型中没有views字段
      // if (includeViews) {
      //   await this.databaseService.post.update({
      //     where: { id },
      //     data: { views: { increment: 1 } },
      //   });
      // }

      return this.transformToContentResponse(post)
    } catch (error) {
      if (error instanceof NotFoundException) {
        throw error
      }
      this.logger.error(`Failed to get post: ${error.message}`, error.stack, 'ContentService')
      throw new BadRequestException('获取文章详情失败')
    }
  }

  // 更新文章
  async updatePost(
    id: string,
    data: {
      title?: string
      content?: string
      excerpt?: string
      categoryId?: string
      tags?: string[]
      status?: PostStatus
    },
    userId: string,
    userRole: UserRole
  ) {
    try {
      const existingPost = await this.databaseService.post.findUnique({
        where: { id },
        include: { author: true }
      })

      if (!existingPost) {
        throw new NotFoundException('文章不存在')
      }

      // 权限检查：只有作者本人或管理员可以编辑
      if (existingPost.authorId !== userId && !['ADMIN', 'SUPER_ADMIN'].includes(userRole)) {
        throw new BadRequestException('无权限编辑此文章')
      }

      const updateData: any = {
        ...data,
        updatedAt: new Date()
      }

      // 处理标签更新
      if (data.tags) {
        // 先删除现有标签关联
        await this.databaseService.postTag.deleteMany({
          where: { postId: id }
        })

        // 创建新的标签关联
        updateData.tags = {
          create: data.tags.map(tagId => ({
            tag: { connect: { id: tagId } }
          }))
        }
      }

      const updatedPost = await this.databaseService.post.update({
        where: { id },
        data: updateData,
        include: {
          author: { select: { id: true, username: true, email: true } },
          category: true,
          tags: { include: { tag: true } }
        }
      })

      this.logger.log(`Post updated: ${id}`, 'ContentService')
      return this.transformToContentResponse(updatedPost)
    } catch (error) {
      if (error instanceof NotFoundException || error instanceof BadRequestException) {
        throw error
      }
      this.logger.error(`Failed to update post: ${error.message}`, error.stack, 'ContentService')
      throw new BadRequestException('更新文章失败')
    }
  }

  // 删除文章
  async deletePost(id: string, userId: string, userRole: UserRole) {
    try {
      const existingPost = await this.databaseService.post.findUnique({
        where: { id },
        include: { author: true }
      })

      if (!existingPost) {
        throw new NotFoundException('文章不存在')
      }

      // 权限检查：只有作者本人或管理员可以删除
      if (existingPost.authorId !== userId && !['ADMIN', 'SUPER_ADMIN'].includes(userRole)) {
        throw new BadRequestException('无权限删除此文章')
      }

      // 删除相关数据
      await this.databaseService.$transaction([
        this.databaseService.postTag.deleteMany({ where: { postId: id } }),
        this.databaseService.comment.deleteMany({ where: { postId: id } }),
        this.databaseService.post.delete({ where: { id } })
      ])

      this.logger.log(`Post deleted: ${id}`, 'ContentService')
      return { message: '文章删除成功' }
    } catch (error) {
      if (error instanceof NotFoundException || error instanceof BadRequestException) {
        throw error
      }
      this.logger.error(`Failed to delete post: ${error.message}`, error.stack, 'ContentService')
      throw new BadRequestException('删除文章失败')
    }
  }

  // 发布文章
  async publishPost(id: string, userId: string, userRole: UserRole) {
    try {
      const post = await this.databaseService.post.findUnique({
        where: { id }
      })

      if (!post) {
        throw new NotFoundException('文章不存在')
      }

      // 权限检查
      if (post.authorId !== userId && !['ADMIN', 'SUPER_ADMIN', 'EDITOR'].includes(userRole)) {
        throw new BadRequestException('无权限发布此文章')
      }

      const updatedPost = await this.databaseService.post.update({
        where: { id },
        data: {
          status: PostStatus.PUBLISHED,
          publishedAt: new Date()
        },
        include: {
          author: { select: { id: true, username: true, email: true } },
          category: true,
          tags: { include: { tag: true } }
        }
      })

      this.logger.log(`Post published: ${id}`, 'ContentService')
      return this.transformToContentResponse(updatedPost)
    } catch (error) {
      if (error instanceof NotFoundException || error instanceof BadRequestException) {
        throw error
      }
      this.logger.error(`Failed to publish post: ${error.message}`, error.stack, 'ContentService')
      throw new BadRequestException('发布文章失败')
    }
  }

  // 获取热门文章
  async getPopularPosts(limit = 10) {
    try {
      const posts = await this.databaseService.post.findMany({
        where: { status: PostStatus.PUBLISHED },
        orderBy: { publishedAt: 'desc' },
        take: limit,
        include: {
          author: { select: { id: true, username: true } },
          category: true,
          _count: { select: { comments: true } }
        }
      })

      return posts
    } catch (error) {
      this.logger.error(`Failed to get popular posts: ${error.message}`, error.stack, 'ContentService')
      throw new BadRequestException('获取热门文章失败')
    }
  }

  // 获取最新文章
  async getLatestPosts(limit = 10) {
    try {
      const posts = await this.databaseService.post.findMany({
        where: { status: PostStatus.PUBLISHED },
        orderBy: { publishedAt: 'desc' },
        take: limit,
        include: {
          author: { select: { id: true, username: true } },
          category: true,
          _count: { select: { comments: true } }
        }
      })

      return posts
    } catch (error) {
      this.logger.error(`Failed to get latest posts: ${error.message}`, error.stack, 'ContentService')
      throw new BadRequestException('获取最新文章失败')
    }
  }

  // 切换收藏状态
  async toggleBookmark(postId: string, userId: string) {
    try {
      // 这里需要实现收藏功能，暂时返回成功状态
      this.logger.log(`Toggle bookmark for post ${postId} by user ${userId}`, 'ContentService')
      return { bookmarked: true }
    } catch (error) {
      this.logger.error(`Failed to toggle bookmark: ${error.message}`, error.stack, 'ContentService')
      throw new BadRequestException('切换收藏状态失败')
    }
  }

  // 根据作者查找文章
  async findByAuthor(authorId: string, queryDto: any) {
    const { page = 1, limit = 10, sortBy = 'createdAt', sortOrder = 'DESC' } = queryDto
    const skip = (page - 1) * limit

    const [posts, total] = await Promise.all([
      this.databaseService.post.findMany({
        where: {
          author: {
            id: authorId
          }
        },
        include: {
          author: true,
          category: true,
          tags: true,
          comments: {
            include: {
              user: true
            }
          }
        },
        orderBy: {
          [sortBy]: sortOrder.toLowerCase()
        },
        skip,
        take: limit
      }),
      this.databaseService.post.count({
        where: {
          author: {
            id: authorId
          }
        }
      })
    ])

    const items = posts.map(post => this.transformToContentResponse(post))
    return new PaginatedResponseDto(items, total, page, limit)
  }

  async importContent(file: Express.Multer.File, userId: string) {
    // TODO: 实现内容导入功能
    // 这里应该解析文件内容并批量创建内容
    return {
      total: 0,
      success: 0,
      failed: 0,
      errors: []
    }
  }

  async getRelatedContent(id: string, limit: number = 5) {
    // TODO: 实现相关内容推荐功能
    // 这里应该基于标签、分类等找到相关内容
    return []
  }

  async toggleLike(id: string, userId: string) {
    // TODO: 实现点赞/取消点赞功能
    // 这里应该切换用户对内容的点赞状态
    return {
      liked: true,
      likesCount: 1
    }
  }

  async uploadMedia(id: string, files: Express.Multer.File[], userId: string) {
    // TODO: 实现媒体文件上传功能
    // 这里应该处理文件上传并关联到内容
    return {
      uploaded: files.length,
      files: files.map(file => ({
        id: 'temp-id',
        filename: file.originalname,
        url: '/uploads/' + file.filename,
        size: file.size
      }))
    }
  }

  async batchOperation(batchDto: any, userId: string) {
    // TODO: 实现批量操作功能
    // 这里应该处理批量删除、发布等操作
    return {
      success: 0,
      failed: 0,
      errors: []
    }
  }

  async exportContent(exportDto: any, userId: string) {
    // TODO: 实现内容导出功能
    // 这里应该导出内容为指定格式
    return {
      filename: 'content-export.xlsx',
      url: '/exports/content-export.xlsx',
      size: 1024
    }
  }

  async publish(id: string, publishDto: any, userId: string) {
    // TODO: 实现发布功能
    const content = await this.databaseService.post.update({
      where: { id },
      data: {
        status: PostStatus.PUBLISHED,
        publishedAt: new Date()
      },
      include: {
        author: {
          select: {
            id: true,
            username: true,
            email: true
          }
        },
        category: true,
        tags: {
          include: {
            tag: true
          }
        }
      }
    })
    return this.transformToContentResponse(content)
  }

  async unpublish(id: string, userId: string) {
    // TODO: 实现取消发布功能
    const content = await this.databaseService.post.update({
      where: { id },
      data: {
        status: PostStatus.DRAFT,
        publishedAt: null
      },
      include: {
        author: {
          select: {
            id: true,
            username: true,
            email: true
          }
        },
        category: true,
        tags: {
          include: {
            tag: true
          }
        }
      }
    })
    return this.transformToContentResponse(content)
  }

  async duplicate(id: string, title: string, userId: string) {
    // TODO: 实现复制功能
    const original = await this.databaseService.post.findUnique({
      where: { id }
    })

    if (!original) {
      throw new Error('Content not found')
    }

    const duplicated = await this.databaseService.post.create({
      data: {
        title: title || `${original.title} (副本)`,
        slug: this.generateSlug(title || `${original.title} (副本)`),
        content: original.content,
        excerpt: original.excerpt,
        status: PostStatus.DRAFT,
        author: { connect: { id: userId } }
      },
      include: {
        author: {
          select: {
            id: true,
            username: true,
            email: true
          }
        },
        category: true,
        tags: {
          include: {
            tag: true
          }
        }
      }
    })
    return this.transformToContentResponse(duplicated)
  }

  async getVersions(id: string, options: { page: number; limit: number }, userId: string) {
    // TODO: 实现版本历史功能
    return new PaginatedResponseDto([], 0, options.page, options.limit)
  }

  // 添加控制器需要的方法
  async create(createContentDto: any, userId: string) {
    return this.createPost(createContentDto, userId)
  }

  async findAll(queryDto: QueryContentDto): Promise<PaginatedResponseDto<ContentResponseDto>> {
    const {
      page = 1,
      limit = 10,
      type,
      status,
      categoryId,
      tags,
      authorId,
      search,
      sortBy = 'createdAt',
      sortOrder = 'desc'
    } = queryDto

    const skip = (page - 1) * limit
    const where: any = {}

    if (type) where.type = type
    if (status) where.status = status
    if (categoryId) where.categoryId = categoryId
    if (authorId) where.authorId = authorId
    if (search) {
      where.OR = [
        { title: { contains: search, mode: 'insensitive' } },
        { content: { contains: search, mode: 'insensitive' } },
        { excerpt: { contains: search, mode: 'insensitive' } }
      ]
    }

    // 处理标签查询
    if (tags) {
      where.tags = {
        some: {
          tag: {
            name: {
              in: tags.split(',').map(tag => tag.trim())
            }
          }
        }
      }
    }

    const [posts, total] = await Promise.all([
      this.databaseService.post.findMany({
        where,
        skip,
        take: limit,
        orderBy: { [sortBy]: sortOrder },
        include: {
          author: {
            select: {
              id: true,
              username: true,
              email: true
            }
          },
          category: true,
          tags: {
            include: {
              tag: true
            }
          }
        }
      }),
      this.databaseService.post.count({ where })
    ])

    const items = posts.map(post => this.transformToContentResponse(post))

    return new PaginatedResponseDto(items, total, page, limit)
  }

  async findDrafts(queryDto: QueryContentDto, userId: string): Promise<PaginatedResponseDto<ContentResponseDto>> {
    const modifiedQuery = { ...queryDto, status: ContentStatus.DRAFT, authorId: userId }
    return this.findAll(modifiedQuery)
  }

  async findPublished(queryDto: QueryContentDto): Promise<PaginatedResponseDto<ContentResponseDto>> {
    const modifiedQuery = { ...queryDto, status: ContentStatus.PUBLISHED }
    return this.findAll(modifiedQuery)
  }

  async getStats(userId: string): Promise<ContentStatsDto> {
    const [totalPosts, publishedPosts, draftPosts, archivedPosts] = await Promise.all([
      this.databaseService.post.count({ where: { authorId: userId } }),
      this.databaseService.post.count({ where: { authorId: userId, status: PostStatus.PUBLISHED } }),
      this.databaseService.post.count({ where: { authorId: userId, status: PostStatus.DRAFT } }),
      this.databaseService.post.count({ where: { authorId: userId, status: PostStatus.ARCHIVED } })
    ])

    return {
      totalContent: totalPosts,
      publishedContent: publishedPosts,
      draftContent: draftPosts,
      archivedContent: archivedPosts,
      reviewingContent: 0, // TODO: 实现审核状态统计
      totalViews: 0, // TODO: 实现浏览量统计
      totalLikes: 0, // TODO: 实现点赞统计
      totalComments: 0, // TODO: 实现评论统计
      totalBookmarks: 0, // TODO: 实现收藏统计
      byType: {} as Record<ContentType, number>, // TODO: 实现按类型统计
      byStatus: {} as Record<ContentStatus, number>, // TODO: 实现按状态统计
      recentContent: 0, // TODO: 实现最近内容统计
      popularContent: [], // TODO: 实现热门内容统计
      latestContent: [] // TODO: 实现最新内容统计
    }
  }

  async search(searchParams: any): Promise<PaginatedResponseDto<ContentResponseDto>> {
    const { query, type, category, page = 1, limit = 20 } = searchParams
    const queryDto: QueryContentDto = {
      page,
      limit,
      search: query,
      type,
      categoryId: category,
      status: ContentStatus.PUBLISHED
    }
    return this.findAll(queryDto)
  }

  async findOne(id: string, includeViews = false) {
    return this.getPostById(id, includeViews)
  }

  async findById(id: string, includeViews = false) {
    const post = await this.databaseService.post.findUnique({
      where: { id },
      include: {
        author: {
          select: {
            id: true,
            username: true,
            email: true
          }
        },
        category: true,
        tags: {
          include: {
            tag: true
          }
        }
      }
    })

    if (!post) {
      throw new NotFoundException('内容不存在')
    }

    return this.transformToContentResponse(post)
  }

  async update(id: string, updateContentDto: any, userId: string) {
    // 获取用户角色，这里暂时使用默认值
    const userRole = UserRole.USER // TODO: 从用户服务获取实际角色
    return this.updatePost(id, updateContentDto, userId, userRole)
  }

  async remove(id: string, userId: string) {
    return this.deletePost(id, userId, UserRole.USER) // TODO: 获取实际用户角色
  }

  async incrementViews(id: string) {
    // 由于Post模型中没有views字段，这里只记录日志
    this.logger.log(`Increment views for post ${id}`, 'ContentService')
    return { success: true }
  }
}
